/**
 ******************************************************************************
 * @file	TR700Driver.c
 * @brief	TR700 光源、光功模块驱动

包括串口、PWM、定时器、STM32内部Flash存储、LED、PIN读取、外设电源开关、SPI

所有模块只有两个函数接口 Init_xxx、Ctrl_xxx
- 2017-5-22,MenglongWu,MenglongWoo@aliyun.com
*/
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include "stm32f10x_dma.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_spi.h"
#include "flash.h"
#include "stm32f10x.h"
#include "prj_type.h"
#include "usart.h"						//串口
#include "minishell-tiny.h"
#include "TR700Driver.h"
#include "project.h"
#include <env.h>



volatile unsigned long  jiffies = 0;

void Delay_ms(uint16_t ms)
{
	// g_delay_ms = ms;
	// while(g_delay_ms);
	unsigned long after = jiffies + ms * _1MS;
	while (time_before(jiffies, after));
}

/**
 * @brief	配置串口
 * @param
 * @retval\n	NULL
 * @remarks	波特率115200，用于输出调试信息
 */

void USART_Configuration()
{
	USART_InitTypeDef USART_InitStructure;
	struct com_dev comdev;
	//u8 KeyNum = 0;
	//uint32_t IntDeviceSeriNum[3];

	USART_InitStructure.USART_BaudRate				= 115200;
	USART_InitStructure.USART_WordLength			= USART_WordLength_8b;
	USART_InitStructure.USART_StopBits				= USART_StopBits_1;
	USART_InitStructure.USART_Parity				= USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode					= USART_Mode_Rx | USART_Mode_Tx;

	//comdev.usart = COM_B6B7;
	comdev.usart		= COM_A9A10;
	comdev.dma_tch		= DMA1_Channel4;
	comdev.dma_rch		= DMA1_Channel5;
	comdev.dma_f_tch	= DMA1_FLAG_TC4;
	comdev.dma_f_rch	= DMA1_FLAG_TC5;
	CommInit(&comdev, &USART_InitStructure);


	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	USART_Cmd(USART1, ENABLE);

	{
		NVIC_InitTypeDef NVIC_InitStructure;
		NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
	}
	// CommDMAMode(0);
}



// ***************************************************************************
// LED 显示

#define RCC_LED_LS     	RCC_APB2Periph_GPIOC
#define GROUP_LED_LS   	GPIOC
#define PIN_LED_LS     	GPIO_Pin_10

#define RCC_LED_OPM     RCC_APB2Periph_GPIOC
#define GROUP_OPM   	GPIOC
#define PIN_OPM     	GPIO_Pin_11


#define RCC_OPM     	RCC_APB2Periph_GPIOC
#define GROUP_OPM   	GPIOC
#define PIN_OPM     	GPIO_Pin_11

void Init_LED()
{
	GPIO_InitTypeDef GPIO_InitStructure;


	// 脉冲激光器 LED
	RCC_APB2PeriphClockCmd(RCC_LED_LS, ENABLE);
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Pin	= PIN_LED_LS;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_Out_PP;
	GPIO_Init(GROUP_LED_LS, &GPIO_InitStructure);
	GPIO_SetBits(GROUP_LED_LS, PIN_LED_LS);

	// 连续激光器 LED
	RCC_APB2PeriphClockCmd(RCC_LED_OPM, ENABLE);
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Pin	= PIN_OPM;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_Out_PP;
	GPIO_Init(GROUP_OPM, &GPIO_InitStructure);
	GPIO_SetBits(GROUP_OPM, PIN_OPM);


	// Ctrl_LED(CTRL_LED_LS, 0);
	// Ctrl_LED(CTRL_LED_OPM, 0);
}


// #define CTRL_LED_LS 	0
// #define CTRL_LED_OPM 	1
// #define LED_ON          1
// #define LED_OFF         0
void Ctrl_LED(int index, int val)
{
	GPIO_TypeDef *group;
	uint16_t io;


	switch(index) {
	case CTRL_LED_LS:
		group = GROUP_LED_LS;
		io = PIN_LED_LS;
		break;
	case CTRL_LED_OPM:
		group = GROUP_OPM;
		io = PIN_OPM;
		break;
	}
	if (val == 0) {
		GPIO_ResetBits(group, io);
	} else {
		GPIO_SetBits(group, io);
	}

}


/**
 * @brief	用于定时，定时1ms
 * @param\n
 * @retval\n	NULL
 * @remarks
 */
void TIM6_Init()
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	/* TIM3 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	//时钟72M    1ms中断  向上计数
	TIM_TimeBaseStructure.TIM_Period		= 10 - 1;
	TIM_TimeBaseStructure.TIM_Prescaler		= 7200 - 1;
	TIM_TimeBaseStructure.TIM_CounterMode	= TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

	TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
	TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); //开定时器中断
	TIM_Cmd(TIM6, ENABLE);
}

extern unsigned char usart_rx[64];
extern int usart_rx_index;

int PeekUartCmd()
{
	static char buf[64];
	static int   offset = 0;
	char *pstart;

	int   len = 0;
	char *cmd[8];
	int   count = 0;
	char  seps[] = " ,\t";
	char  token = NULL;

	struct sh_detach_depth depth;

	depth.cmd = cmd;
	depth.len = 8;
	depth.seps = " \t";


	pstart = buf + offset;
	if (usart_rx_index) {
		memcpy(pstart, usart_rx, usart_rx_index);
		len = usart_rx_index;
		usart_rx_index = 0;
	}



	if (len) {

		*(pstart + len) = '\0';
		printf("%s", pstart);
		offset += len;
		if (*(pstart) == '\r') {
			*(pstart) = '\0';
			printf("\r\n");
			sh_analyse_ex(buf, offset, &depth, NULL);
			offset = 0;

		}


		if (offset == sizeof(buf)) {
			offset = 0;
		}
	}

}

int ReadUart(char *out, int max)
{
	int len = 0;
	if (usart_rx_index) {
		if (usart_rx_index > max) {
			len = max;
		} else {
			len = usart_rx_index;
		}
		usart_rx_index = 0;
		memcpy(out, usart_rx, len);
		return len;
	}
	return 0;
}































/**
 * @brief	从内部FLASH读取校准信息，以及配置信息
 * @param\n
 * @retval\n	NULL
 * @remarks
 */
struct adj_power_flash g_adj_power;		/*< 校准参数 */
void FLASH_Configuration()
{
	uint32_t i;
#if 0
	ReadFlash(FLASH_PAGE_PRODUCT,
	          (uint32_t *) & (g_adj_power),
	          sizeof(struct adj_power_flash));
	if(g_adj_power.flag != 0x11223344) {

		g_adj_power._adc   = 300;
		g_adj_power._dac   = 300;

		g_adj_power._adc1  = 350;
		g_adj_power._dac1  = 300;
		g_adj_power._adc2  = 350;
		g_adj_power._dac2  = 300;
		g_adj_power._adc3  = 350;
		g_adj_power._dac3  = 300;

		g_adj_power._5_adc1 = 950;
		g_adj_power._5_dac1 = 1106;
		g_adj_power._5_adc2 = 950;
		g_adj_power._5_dac2 = 1106;
		g_adj_power._5_adc3 = 950;
		g_adj_power._5_dac3 = 1106;

		for(i = 0; i < 24; ++i) {
			g_adj_power.sn[i] = '?';
		}
		g_adj_power.sn[24] = '\0';

		g_adj_power._650_en  = 1;//650
		g_adj_power._1310_en = 1;//1310
		g_adj_power._1490_en = 0;//1490
		g_adj_power._1550_en = 1;//1550


		g_adj_power._logo_addr = 0x0000000;//logo地址
		g_adj_power._logo_backcolor = 0x22f2;//logo背景色
		g_adj_power._logo_w = 243;//logo宽度，宽高有最大限制
		g_adj_power._logo_h = 57;//logo高度



		g_adj_power.en_ch1 = 1;
		g_adj_power.en_ch2 = 0;
		g_adj_power.en_ch3 = 1;

		g_adj_power._ch1wave = 1310;//默认波长值
		g_adj_power._ch2wave = 1625;
		g_adj_power._ch3wave = 1550;

		g_adj_power.lv1_low   = 400;
		g_adj_power.lv1_high  = 4000;
		g_adj_power.lv2_low   = 400;
		g_adj_power.lv2_high  = 4000;
		g_adj_power.lv3_low   = 400;
		g_adj_power.lv3_high  = 4000;
		g_adj_power.lv4_low   = 400;
		g_adj_power.lv4_high  = 4000;
		g_adj_power.lv5_low   = 400;
		g_adj_power.lv5_high  = 4000;
		g_adj_power.lv6_low   = 400;
		g_adj_power.lv6_high  = 4000;
		g_adj_power.lv7_low   = 400;
		g_adj_power.lv7_high  = 4000;

	}
	printf("Load config from FLASH\r\n");
	printf("------------------------------------------------\r\n");
	printf("SN:%s\r\n", g_adj_power.sn);
	printf("Out:%4.4d\tIn:%4.4d\r\n", (uint32_t)g_adj_power._adc, (uint32_t)g_adj_power._dac);
	printf("Product Configuration\r\n");
	printf("    |650\t|%s\t",
	       g_adj_power._650_en ? "On" : "Off");
	printf("    |1310\t|%s\r\n",
	       g_adj_power._1310_en ? "On" : "Off");
	printf("    |1490\t|%s\t",
	       g_adj_power._1490_en ? "On" : "Off");
	printf("    |1550\t|%s\r\n",
	       g_adj_power._1550_en ? "On" : "Off");


	printf("------------------------------------------------\r\n");
	// show_ls();
	// show_opm();
	// if (g_adj_power._logo_backcolor) {
	// 	g_sm_mm_color = Yellow;
	// } else {
	// 	g_sm_mm_color = RGB565CONVERT(0xff, 0x7b, 0x3c);
	// }

	Init_Overflow(&g_adj_power);
#else
	ReadFlash(FLASH_PAGE_PRODUCT,
	          (uint32_t *) & (g_sys_env),
	          sizeof(struct sys_env));
	do_printenv();
	if (-1 == isvalid_env()) {
		printf("无效............\r\n");
		copy_def_env();
	}
	// show_ls();
	// show_opm();
	// if (g_adj_power._logo_backcolor) {
	// 	g_sm_mm_color = Yellow;
	// } else {
	// 	g_sm_mm_color = RGB565CONVERT(0xff, 0x7b, 0x3c);
	// }
	
#endif

}

void Flash_Save()
{
#if 0
	g_adj_power.flag = 0x11223344;
	WriteFlash(FLASH_PAGE_PRODUCT,
	           (uint32_t *) & (g_adj_power),
	           sizeof(struct adj_power_flash));
#else
	calc_hash();
	if (-1 == isvalid_env()) {
	}
	// calc_hash();
	// if (-1 == isvalid_env()) {
	// }
	// calc_hash();
	// if (-1 == isvalid_env()) {
	// }
	printf("sizeof(struct sys_env) %d\r\n", sizeof(struct sys_env));
	WriteFlash(FLASH_PAGE_PRODUCT,
	           (uint32_t *) & (g_sys_env),
	           sizeof(struct sys_env));
#endif
}




//***************************************************************

extern char spi_dates[100];
DMA_InitTypeDef DMA_InitStructure;
void ReDMA()
{
	DMA_ClearFlag(DMA1_FLAG_TC4);
	DMA_Cmd(DMA1_Channel4, DISABLE);
	DMA_InitStructure.DMA_BufferSize = 4;
	DMA_Cmd(DMA1_Channel4, ENABLE);
}
void SPI_DMA()
{
#if 0
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;

	/* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
	DMA_DeInit(DMA1_Channel5);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;                          //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_dates;                    //设置 SRAM 存储地址(目的地址)
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                //传输方向 外设-内存
	DMA_InitStructure.DMA_BufferSize = 16;                         //设置 SPI1 发送长度
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel5, &DMA_InitStructure);

	DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
	/* Enable SPI1 DMA RX request */
	SPI2->CR2 |= 1 << 0;                                                               //接收缓冲区DMA使能
	DMA_Cmd(DMA1_Channel5, ENABLE);

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
	NVIC_Init(&NVIC_InitStructure);

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
	DMA_ClearFlag(DMA1_FLAG_TC5);

#endif

	NVIC_InitTypeDef NVIC_InitStructure;

	printf("1 dma ISR %8x\r\n", DMA1->ISR);
	DMA_Cmd(DMA1_Channel4, DISABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);


	/* DMA1 Channel4 Configures for SPIS Receive */
	DMA_DeInit(DMA1_Channel4);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR);
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&spi_dates;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = 4;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel4, &DMA_InitStructure);

	if(DMA_GetITStatus(DMA1_IT_TC4) != RESET) {
		DMA_ClearITPendingBit(DMA1_IT_TC4);
	}
	DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
	SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);





	/* Enable the DMA1_Channel4、DMA1_Channel5 Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
	// NVIC_Init(&NVIC_InitStructure);
	printf("2 dma ISR %8x\r\n", DMA1->ISR);
	/* Enable SPI2  */
	SPI_Cmd(SPI2, ENABLE);
	DMA_Cmd(DMA1_Channel4, ENABLE);
}
SPI_InitTypeDef SPI_InitStructure_r;
void SPI_OnlyTX()
{
	SPI_Cmd(SPI2, DISABLE);
	SPI_InitStructure_r.SPI_Direction = SPI_Direction_1Line_Tx;
	// SPI_InitStructure_r.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_Init(SPI2, &SPI_InitStructure_r);
	// SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
	SPI_Cmd(SPI2, ENABLE);
}

void SPI_OnlyRX()
{
	SPI_Cmd(SPI2, DISABLE);
	// SPI_InitStructure_r.SPI_Direction = SPI_Direction_2Lines_RxOnly;
	SPI_InitStructure_r.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_Init(SPI2, &SPI_InitStructure_r);
	// SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
	SPI_Cmd(SPI2, ENABLE);
	// SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
}

void SPI_Off()
{
	// SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
	SPI_Cmd(SPI2, DISABLE);
}

void SPI_Slave(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	NVIC_InitTypeDef NVIC_InitStructure;



	//Enable SPI2 clock and GPIO clock for SPI2 and SPI
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	//IO初始化
	//Configure SPI2 pins: SCK, MISO and MOSI
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	// // mISO
	// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	// GPIO_Init(GPIOB, &GPIO_InitStructure);
	// // MOSI CLK
	// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |  GPIO_Pin_15 ;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	// GPIO_Init(GPIOB, &GPIO_InitStructure);
	// // NSS
	// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	// GPIO_Init(GPIOB, &GPIO_InitStructure);
	//1st phase: SPI2 slave
	//SPI1 Config
	SPI_InitStructure_r.SPI_Direction = SPI_Direction_2Lines_RxOnly;//只接收，不发送，这个地方是重点，如果设置为单工通信是不能实现数据采集的。
	// SPI_InitStructure_r.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure_r.SPI_Mode = SPI_Mode_Slave; //从机模式
	// SPI_InitStructure_r.SPI_Mode = SPI_Mode_Master; //从机模式
	// SPI_InitStructure_r.SPI_Mode = SPI_Mode_Master; //从机模式
	SPI_InitStructure_r.SPI_DataSize = SPI_DataSize_8b; //数据位为8
	SPI_InitStructure_r.SPI_CPOL = SPI_CPOL_Low; //不发送数据时，时钟线为高
	// SPI_InitStructure_r.SPI_CPHA = SPI_CPHA_2Edge; //在第二个沿进行采样
	SPI_InitStructure_r.SPI_CPHA = SPI_CPHA_1Edge; //在第二个沿进行采样
	// SPI_InitStructure_r.SPI_NSS = SPI_NSS_Hard; //硬NSS
	SPI_InitStructure_r.SPI_NSS = SPI_NSS_Soft; //硬NSS
	SPI_InitStructure_r.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
	// SPI_InitStructure_r.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
	SPI_InitStructure_r.SPI_FirstBit = SPI_FirstBit_MSB; //MSB优先
	SPI_InitStructure_r.SPI_CRCPolynomial = 7;
	SPI_Init(SPI2, &SPI_InitStructure_r);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //使用中断进行接收，因此设置NVIC的优先机组，1表示1bit抢占优先级
#if 1
	NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	/* Enable SPI2 RXNE interrupt*/
	SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
#endif
	//Enable SPI2

	// SPI_DMA();
	SPI_Cmd(SPI2, ENABLE); //先不启动SPI，在收到特定命令的时候再启动


}
void SPI_Master(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef SPI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	//Enable SPI2 clock and GPIO clock for SPI2 and SPI
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
	//IO初始化
	//Configure SPI2 pins: SCK, MISO and MOSI
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	// GPIO_Init(GPIOB, &GPIO_InitStructure);

	// // mISO
	// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	// GPIO_Init(GPIOB, &GPIO_InitStructure);
	// MOSI CLK
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |  GPIO_Pin_15 | GPIO_Pin_14 ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	// NSS
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	// 1st phase: SPI2 slave
	// SPI1 Config
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//只接收，不发送，这个地方是重点，如果设置为单工通信是不能实现数据采集的。
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1, &SPI_InitStructure);
	//Enable SPI2
	SPI_Cmd(SPI2, ENABLE); //先不启动SPI，在收到特定命令的时候再启动
}

void EXTI_SPI()
{
	EXTI_InitTypeDef   EXTI_InitStructure;
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;

	//移植：这里定义需要扫描的端口和端口组，此端口必须是外部中断端口


	//端口方向
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	//清空中断标志
	EXTI_ClearITPendingBit(EXTI_Line12);

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);

	EXTI_InitStructure.EXTI_Line = GPIO_Pin_12;//EXTI_Linex 和 GPIO_Pin_x相同
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	//外部中断属性
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//移植：添加使用到的中断
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_Init(&NVIC_InitStructure);
	EXTI_ClearITPendingBit(EXTI_Line12);


	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
	NVIC_Init(&NVIC_InitStructure);
	DMA_ClearITPendingBit(DMA1_IT_TC5);
}